/**
 * ComfyUI Prompt Translator Frontend Extension
 * Adds custom translation buttons with direct execution
 */

import { app } from "../../scripts/app.js";
import { ComfyWidgets } from "../../scripts/widgets.js";

// Extension name
const EXTENSION_NAME = "BuimenLabo_PromptTranslator";

// Custom button widget creation
function createTranslationButton(node, name, label, callback) {
    const button = document.createElement("button");
    button.textContent = label;
    button.className = "comfy-button translate-button";
    button.style.cssText = `
        width: 190px;
        height: 35px;
        background: #4a90e2;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 14px;
        font-weight: bold;
        margin: 2px;
        transition: background-color 0.2s;
    `;
    
    button.addEventListener("click", callback);
    button.addEventListener("mouseenter", () => {
        if (!button.disabled) {
            button.style.background = "#5aa0f2";
        }
    });
    button.addEventListener("mouseleave", () => {
        if (!button.disabled) {
            button.style.background = "#4a90e2";
        }
    });
    
    return button;
}

// Enhanced node creation with custom buttons
function enhancePromptTranslatorNode(node) {
    // Set node properties
    node.properties = node.properties || {};
    node.properties.translating = false;
    
    // Add input text change listener for real-time token counting
    const originalOnInputChange = node.onInputChange;
    node.onInputChange = function() {
        if (originalOnInputChange) {
            originalOnInputChange.call(this);
        }
        updateTokenCountDisplay(this);
    };
    
    // Watch for widget value changes
    const originalOnWidgetChange = node.onWidgetChange;
    node.onWidgetChange = function(widget) {
        if (originalOnWidgetChange) {
            originalOnWidgetChange.call(this, widget);
        }
        if (widget.name === "input_text") {
            updateTokenCountDisplay(this);
        }
    };
    
    // Add single translation button
    const buttonContainer = document.createElement("div");
    buttonContainer.className = "translation-button-container";
    buttonContainer.style.cssText = `
        display: flex;
        margin: 5px 0;
        justify-content: center;
    `;
    
    // Single Translation button
    const translateButton = createTranslationButton(
        node,
        "execute_translation",
        "Translation",
        () => executeTranslation(node)
    );
    
    translateButton.style.width = "390px";  // Full width
    
    buttonContainer.appendChild(translateButton);
    
    // Add button to node
    node.addDOMWidget("translation_button", "div", buttonContainer);
    
    // Add token counter display
    const tokenContainer = document.createElement("div");
    tokenContainer.className = "token-counter-container";
    tokenContainer.style.cssText = `
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 8px;
        background: #1a1a1a;
        border-radius: 4px;
        margin: 5px 0;
        border: 1px solid #555;
    `;
    
    const tokenLabel = document.createElement("span");
    tokenLabel.textContent = "Tokens: 0";
    tokenLabel.style.cssText = `
        font-family: monospace;
        font-size: 12px;
        color: white;
        font-weight: bold;
    `;
    
    const statusLabel = document.createElement("span");
    statusLabel.textContent = "Ready";
    statusLabel.style.cssText = `
        font-family: monospace;
        font-size: 12px;
        color: #ccc;
    `;
    
    tokenContainer.appendChild(tokenLabel);
    tokenContainer.appendChild(statusLabel);
    node.addDOMWidget("token_counter", "div", tokenContainer);
    
    // Store references for easy access
    node.translateButton = translateButton;
    node.tokenLabel = tokenLabel;
    node.statusLabel = statusLabel;
    
    // Add input text monitoring
    setTimeout(() => {
        const inputWidget = node.widgets.find(w => w.name === "input_text");
        if (inputWidget && inputWidget.element) {
            inputWidget.element.addEventListener('input', () => {
                updateTokenCountDisplay(node);
            });
        }
    }, 100);
    
    // Initial token count update
    updateTokenCountDisplay(node);
}

// Execute translation directly
async function executeTranslation(node) {
    // Get input text
    const inputWidget = node.widgets.find(w => w.name === "input_text");
    const inputText = inputWidget ? inputWidget.value : "";
    
    if (!inputText.trim()) {
        alert("Please enter text to translate");
        return;
    }
    
    // Get translation settings
    const providerWidget = node.widgets.find(w => w.name === "provider");
    const translationModeWidget = node.widgets.find(w => w.name === "translation_mode");
    const otherLanguageWidget = node.widgets.find(w => w.name === "other_language");
    const apiKeyWidget = node.widgets.find(w => w.name === "api_key");
    const translatedTextWidget = node.widgets.find(w => w.name === "translated_text");
    
    const provider = providerWidget ? providerWidget.value : "Google";
    const translationMode = translationModeWidget ? translationModeWidget.value : "Other Language → English";
    const otherLanguage = otherLanguageWidget ? otherLanguageWidget.value : "Japanese";
    const apiKey = apiKeyWidget ? apiKeyWidget.value : "";
    
    console.log(`🔄 Translation: "${inputText}" (${translationMode}, ${otherLanguage})`);
    console.log(`📡 Provider: ${provider}, API key: ${apiKey ? 'provided' : 'none'}`);
    
    // Update UI state
    disableButtons(node, true);
    
    try {
        // Show translating status
        if (translatedTextWidget) {
            translatedTextWidget.value = "Translating...";
        }
        
        // Set execute_translation widget to true
        const executeWidget = node.widgets.find(w => w.name === "execute_translation");
        if (executeWidget) {
            executeWidget.value = true;
        }
        
        // Call translation function directly
        let result;
        try {
            console.log(`🚀 Calling translation API...`);
            result = await callTranslationAPINew(provider, inputText, apiKey, translationMode, otherLanguage);
            console.log(`✅ Translation result: "${result}"`);
            
            // Update translated text widget
            if (translatedTextWidget) {
                translatedTextWidget.value = result;
            }
        } catch (error) {
            console.error(`❌ Translation error:`, error);
            throw error;
        }
        
        // Calculate and display token count
        const originalTokens = countTokensSimple(inputText);
        const translatedTokens = countTokensSimple(result);
        const totalTokens = originalTokens + translatedTokens;
        
        if (node.tokenLabel) {
            node.tokenLabel.textContent = `Tokens: ${totalTokens} (${originalTokens}+${translatedTokens})`;
        }
        
        if (node.statusLabel) {
            node.statusLabel.textContent = "Complete";
            node.statusLabel.style.color = "#5cb85c";
        }
        
        // Reset button states
        setTimeout(() => {
            if (jaToEnWidget) jaToEnWidget.value = false;
            if (enToJaWidget) enToJaWidget.value = false;
        }, 100);
        
    } catch (error) {
        console.error("Translation failed:", error);
        const translatedTextWidget = node.widgets.find(w => w.name === "translated_text");
        if (translatedTextWidget) {
            translatedTextWidget.value = `Error: ${error.message}`;
        }
        
        if (node.statusLabel) {
            node.statusLabel.textContent = "Error";
            node.statusLabel.style.color = "#d9534f";
        }
    } finally {
        disableButtons(node, false);
    }
}

// New API call for unified translation
async function callTranslationAPINew(provider, text, apiKey, translationMode, otherLanguage) {
    // For Google free translation, use direct API
    if (provider === "Google" && !apiKey.trim()) {
        // Convert mode to direction for Google API
        const direction = translationMode === "Other Language → English" ? 
            (otherLanguage === "Japanese" ? "日→英" : "other→英") : 
            (otherLanguage === "Japanese" ? "英→日" : "英→other");
        return await translateGoogle(text, direction);
    } else {
        // Use ComfyUI backend API for all other providers
        return await translateViaBackendNew(provider, text, apiKey, translationMode, otherLanguage);
    }
}

// Legacy API call (kept for compatibility)
async function callTranslationAPI(provider, text, apiKey, direction) {
    // For Google free translation, use direct API
    if (provider === "Google" && !apiKey.trim()) {
        return await translateGoogle(text, direction);
    } else {
        // Use ComfyUI backend API for all other providers
        return await translateViaBackend(provider, text, apiKey, direction);
    }
}

// Translate via ComfyUI backend API
async function translateViaBackend(provider, text, apiKey, direction) {
    try {
        console.log(`🌐 Backend API call: ${provider} "${text}" ${direction}`);
        
        // Use FormData as required by ComfyUI
        const formData = new FormData();
        formData.append('provider', provider);
        formData.append('input_text', text);
        formData.append('api_key', apiKey);
        formData.append('direction', direction);
        
        const response = await fetch('/prompt_translator/translate', {
            method: 'POST',
            body: formData
        });
        
        console.log(`📡 Backend response status: ${response.status}`);
        
        if (!response.ok) {
            const errorText = await response.text();
            console.error(`❌ Backend error response:`, errorText);
            throw new Error(`HTTP ${response.status}: ${errorText}`);
        }
        
        const result = await response.json();
        console.log(`📋 Backend response:`, result);
        
        if (!result.success) {
            throw new Error(result.error || 'Translation failed');
        }
        
        return result.translated_text;
        
    } catch (error) {
        console.error(`💥 Backend API error:`, error);
        if (error.name === 'TypeError' && error.message.includes('fetch')) {
            throw new Error(`Backend API not available. Please restart ComfyUI.`);
        }
        throw error;
    }
}

// New backend API call for unified translation
async function translateViaBackendNew(provider, text, apiKey, translationMode, otherLanguage) {
    try {
        console.log(`🌐 Backend API call: ${provider} "${text}" (${translationMode}, ${otherLanguage})`);
        
        // Use FormData as required by ComfyUI
        const formData = new FormData();
        formData.append('provider', provider);
        formData.append('input_text', text);
        formData.append('api_key', apiKey);
        formData.append('translation_mode', translationMode);
        formData.append('other_language', otherLanguage);
        
        const response = await fetch('/prompt_translator/translate_new', {
            method: 'POST',
            body: formData
        });
        
        console.log(`📡 Backend response status: ${response.status}`);
        
        if (!response.ok) {
            const errorText = await response.text();
            console.error(`❌ Backend error response:`, errorText);
            throw new Error(`HTTP ${response.status}: ${errorText}`);
        }
        
        const result = await response.json();
        console.log(`📋 Backend response:`, result);
        
        if (!result.success) {
            throw new Error(result.error || 'Translation failed');
        }
        
        return result.translated_text;
        
    } catch (error) {
        console.error(`💥 Backend API error:`, error);
        if (error.name === 'TypeError' && error.message.includes('fetch')) {
            throw new Error(`Backend API not available. Please restart ComfyUI.`);
        }
        throw error;
    }
}

// Google Translate free API
async function translateGoogle(text, direction) {
    try {
        const sourceLang = direction === "日→英" ? "ja" : "en";
        const targetLang = direction === "日→英" ? "en" : "ja";
        
        const encodedText = encodeURIComponent(text);
        const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sourceLang}&tl=${targetLang}&dt=t&q=${encodedText}`;
        
        const response = await fetch(url);
        const result = await response.json();
        
        if (result && result[0] && result[0][0]) {
            return result[0][0][0];
        } else {
            throw new Error("No translation result");
        }
    } catch (error) {
        throw new Error(`Google translation failed: ${error.message}`);
    }
}

// DeepL API requires backend processing due to CORS
// This function is no longer used - DeepL calls go through Python backend
async function translateDeepL(text, apiKey, direction) {
    throw new Error("DeepL translation must use backend (Run button) due to CORS restrictions");
}

// Simple token counting function
function countTokensSimple(text) {
    if (!text || !text.trim()) {
        return 0;
    }
    
    // Remove extra whitespace and split
    const words = text.trim().split(/\s+/);
    
    // Count tokens: words + punctuation
    let tokenCount = 0;
    for (const word of words) {
        // Count word tokens
        tokenCount += 1;
        
        // Add extra tokens for punctuation
        const punctuationCount = (word.match(/[.,!?;:"()\[\]{}\/-]/g) || []).length;
        tokenCount += punctuationCount;
    }
    
    return Math.max(1, tokenCount); // Ensure at least 1 token for non-empty text
}

// Disable/enable buttons
function disableButtons(node, disabled) {
    if (node.translateButton) {
        node.translateButton.disabled = disabled;
        node.translateButton.style.background = disabled ? "#666" : "#4a90e2";
        node.translateButton.textContent = disabled ? "Translating..." : "Translation";
    }
    
    if (node.statusLabel) {
        if (disabled) {
            node.statusLabel.textContent = "Translating...";
            node.statusLabel.style.color = "#4a90e2";
        } else {
            node.statusLabel.textContent = "Ready";
            node.statusLabel.style.color = "#ccc";
        }
    }
}

// Register extension
app.registerExtension({
    name: EXTENSION_NAME,
    
    async nodeCreated(node) {
        console.log("🔍 Prompt Translator - Node created:", node.comfyClass);
        
        // Support both original and BuimenLabo versions
        if (node.comfyClass === "PromptTranslator" || node.comfyClass === "BuimenLabo_PromptTranslator") {
            console.log("🚀 Enhancing Prompt Translator node:", node.comfyClass);
            enhancePromptTranslatorNode(node);
        }
    },
    
    async setup() {
        // Add custom CSS
        const style = document.createElement("style");
        style.textContent = `
            .translation-buttons-container {
                display: flex;
                gap: 10px;
                margin: 5px 0;
                justify-content: center;
            }
            
            .translate-button {
                width: 190px;
                height: 35px;
                background: #4a90e2;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                font-weight: bold;
                margin: 2px;
                transition: background-color 0.2s;
            }
            
            .translate-button:hover:not(:disabled) {
                background: #5aa0f2;
            }
            
            .translate-button:disabled {
                background: #666;
                cursor: not-allowed;
            }
            
            .translate-button:active {
                background: #3a7bc8;
                transform: translateY(1px);
            }
            
            .token-counter-container {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 8px;
                background: #1a1a1a;
                border-radius: 4px;
                margin: 5px 0;
                border: 1px solid #555;
            }
            
            .token-counter-container span {
                font-family: monospace;
                font-size: 12px;
            }
        `;
        
        document.head.appendChild(style);
    }
});

// Show translation preview and confirmation dialog
function showTranslationPreview(node, provider, inputText, direction, apiKey) {
    // Create modal dialog
    const modal = document.createElement("div");
    modal.className = "translation-preview-modal";
    modal.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.7);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 10000;
        font-family: Arial, sans-serif;
    `;
    
    const dialog = document.createElement("div");
    dialog.style.cssText = `
        background: #2a2a2a;
        border-radius: 8px;
        padding: 20px;
        max-width: 500px;
        width: 90%;
        color: white;
        border: 2px solid #4a90e2;
    `;
    
    const apiKeyDisplay = apiKey ? apiKey.substring(0, 8) + "..." : "None";
    
    dialog.innerHTML = `
        <h3 style="margin: 0 0 15px 0; color: #4a90e2;">🔄 Translation Preview</h3>
        <div style="margin-bottom: 15px;">
            <strong>Provider:</strong> ${provider}<br>
            <strong>Direction:</strong> ${direction}<br>
            <strong>API Key:</strong> ${apiKeyDisplay}
        </div>
        <div style="margin-bottom: 20px;">
            <strong>Text to translate:</strong><br>
            <div style="background: #1a1a1a; padding: 10px; border-radius: 4px; margin-top: 5px; border-left: 3px solid #4a90e2;">
                "${inputText}"
            </div>
        </div>
        <div style="text-align: center;">
            <button id="confirm-translate" style="
                background: #5cb85c;
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 4px;
                margin-right: 10px;
                cursor: pointer;
                font-weight: bold;
            ">✅ Execute Run Button</button>
            <button id="cancel-translate" style="
                background: #d9534f;
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 4px;
                cursor: pointer;
                font-weight: bold;
            ">❌ Cancel</button>
        </div>
        <div style="margin-top: 15px; padding: 10px; background: #333; border-radius: 4px; font-size: 12px; color: #ccc;">
            💡 <strong>Instructions:</strong><br>
            1. Review the translation settings above<br>
            2. Click "Execute Run Button" to proceed<br>
            3. The Run button will be automatically triggered<br>
            4. Translation result will appear in the output
        </div>
    `;
    
    modal.appendChild(dialog);
    document.body.appendChild(modal);
    
    // Add event listeners
    const confirmBtn = dialog.querySelector("#confirm-translate");
    const cancelBtn = dialog.querySelector("#cancel-translate");
    
    confirmBtn.addEventListener("click", async () => {
        document.body.removeChild(modal);
        
        // Update status
        if (node.statusLabel) {
            node.statusLabel.textContent = "Executing...";
            node.statusLabel.style.color = "#4a90e2";
        }
        
        // Auto-trigger the run button
        await autoExecuteRunButton();
    });
    
    cancelBtn.addEventListener("click", () => {
        document.body.removeChild(modal);
        
        // Reset status
        if (node.statusLabel) {
            node.statusLabel.textContent = "Cancelled";
            node.statusLabel.style.color = "#ccc";
        }
        
        const translatedTextWidget = node.widgets.find(w => w.name === "translated_text");
        if (translatedTextWidget) {
            translatedTextWidget.value = "";
        }
    });
    
    // Close on outside click
    modal.addEventListener("click", (e) => {
        if (e.target === modal) {
            cancelBtn.click();
        }
    });
}

// Auto-trigger the Run button
async function autoExecuteRunButton() {
    try {
        // Find and click the queue/run button
        const queueButton = document.querySelector("#queue-button") || 
                          document.querySelector(".queue-button") ||
                          document.querySelector("[title*='Queue']") ||
                          document.querySelector("button:contains('Queue')");
        
        if (queueButton) {
            queueButton.click();
            console.log("Run button triggered successfully");
        } else {
            // Try ComfyUI API methods
            if (app.queuePrompt) {
                const workflow = app.graph.serialize();
                await app.queuePrompt(-1, workflow);
            } else {
                throw new Error("Could not find Run button to execute");
            }
        }
        
    } catch (error) {
        console.error("Auto-execution failed:", error);
        alert(`Failed to execute Run button: ${error.message}\nPlease click the Run button manually.`);
    }
}

// Update token count display
function updateTokenCountDisplay(node) {
    const inputWidget = node.widgets.find(w => w.name === "input_text");
    const translatedTextWidget = node.widgets.find(w => w.name === "translated_text");
    
    if (node.tokenLabel) {
        const inputText = inputWidget ? inputWidget.value : "";
        const translatedText = translatedTextWidget ? translatedTextWidget.value : "";
        
        const inputTokens = countTokensSimple(inputText);
        const translatedTokens = countTokensSimple(translatedText);
        const totalTokens = inputTokens + translatedTokens;
        
        if (translatedText && translatedText.trim()) {
            node.tokenLabel.textContent = `Tokens: ${totalTokens} (${inputTokens}+${translatedTokens})`;
        } else {
            node.tokenLabel.textContent = `Tokens: ${inputTokens}`;
        }
    }
}